#include <iostream>
#include <thread>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <chrono>

std::queue<int> buffer;
const unsigned int BUFFER_SIZE = 10;

std::mutex mtx;
std::condition_variable cv;

void producer(int id, int numItems) {
    for (int i = 0; i < numItems; ++i) {
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait(lock, [] { return buffer.size() < BUFFER_SIZE; });
        
        buffer.push(i);
        std::cout << "Producer " << id << " produced item " << i << std::endl;
        
        lock.unlock();
        cv.notify_all();
        
        std::this_thread::sleep_for(std::chrono::milliseconds(100));  // 模拟生产耗时
    }
}

void consumer(int id, int numItems) {
    for (int i = 0; i < numItems; ++i) {
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait(lock, [] { return !buffer.empty(); });
        
        int item = buffer.front();
        buffer.pop();
        std::cout << "Consumer " << id << " consumed item " << item << std::endl;
        
        lock.unlock();
        cv.notify_all();
        
        std::this_thread::sleep_for(std::chrono::milliseconds(150));  // 模拟消费耗时
    }
}

int main() {
    const int numProducers = 3;
    const int numConsumers = 3;
    const int numItems = 10;

    std::thread producers[numProducers];
    std::thread consumers[numConsumers];
    
    for (int i = 0; i < numProducers; ++i) {
        producers[i] = std::thread(producer, i + 1, numItems);
    }
    
    for (int i = 0; i < numConsumers; ++i) {
        consumers[i] = std::thread(consumer, i + 1, numItems);
    }
    
    for (int i = 0; i < numProducers; ++i) {
        producers[i].join();
    }
    
    for (int i = 0; i < numConsumers; ++i) {
        consumers[i].join();
    }

    return 0;
}
